﻿<!DOCTYPE HTML>
<html lang="zh">
<head>
<title>Loop Files - 语法 &amp; 使用 | AutoHotkey v2</title>
<meta name="description" content="The Loop Files statement retrieves the specified files or folders, one at a time." />
<meta name="ahk:equiv-v1" content="commands/LoopFile.htm" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="../static/theme.css" rel="stylesheet" type="text/css" />
<script src="../static/content.js" type="text/javascript"></script>
<script type="text/javascript">$(function(){0<=window.navigator.userAgent.toLowerCase().indexOf("ucbrowser")&&CaoNiMaDeUc()})</script>
</head>
<body>

<h1>Loop Files</h1>
<p>Retrieves the specified files or folders, one at a time.</p>

<pre class="Syntax"><span class="func">Loop Files</span> FilePattern <span class="optional">, Mode</span></pre>

<h2 id="Parameters">参数</h2>
<dl>

  <dt>FilePattern</dt>
  <dd>
      <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
      <p>The name of a single file or folder, or a wildcard pattern such as "C:\Temp\*.tmp". <em>FilePattern</em> is assumed to be in <a href="../Variables.htm#WorkingDir">A_WorkingDir</a> if an absolute path isn't specified.</p>
      <p>Both asterisks and question marks are supported as wildcards. A match occurs when the pattern appears in either the file's long/normal name or its <a href="#LoopFileShortName">8.3 short name</a>.</p>
      <p>If this parameter is a single file or folder (i.e. no wildcards) and <em>Mode</em> includes <code>R</code>, more than one match will be found if the specified file name appears in more than one of the folders being searched.</p>
  </dd>

  <dt>Mode</dt>
  <dd>
      <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
      <p>An optional string containing zero or more of the following letters:</p>
      <p><code>D</code>: 包含目录(文件夹).<br>
      <code>F</code>: 包含文件. 如果同时省略 F 和 D, 则仅包含文件而不包括目录.<br>
      <code>R</code>: 递归到子目录(子文件夹). 所有子文件夹都将被递归到其中, 而不仅仅是那些名称匹配 <em>FilePattern</em> 的子文件夹. 如果省略 R, 则不包含子目录中的文件和目录.</p>
  </dd>
  
</dl>

<h2>Special Variables Available Inside a File-Loop</h2>
<p>The following variables exist within any file-loop. If an inner file-loop is enclosed by an outer file-loop, the innermost loop's file will take precedence:</p>
<table class="info">
  <tr id="LoopFileName">
    <td>A_LoopFileName</td>
    <td>The name of the file or folder currently retrieved (without the path).</td>
  </tr>
  <tr id="LoopFileExt">
    <td>A_LoopFileExt</td>
    <td>The file's extension (e.g. TXT, DOC, or EXE). The period (.) is not included.</td>
  </tr>
  <tr id="LoopFilePath">
    <td>A_LoopFilePath</td>
    <td>The path and name of the file/folder currently retrieved. If <em>FilePattern</em> contains a relative path rather than an absolute path, the path here will also be relative. In addition, any short (8.3) folder names in <em>FilePattern</em> will still be short (see next item to get the long version).</td>
  </tr>
  <tr id="LoopFileFullPath">
    <td>A_LoopFileFullPath</td>
    <td>This is different than A_LoopFilePath in the following ways: 1) It always contains the absolute/complete path of the file even if <em>FilePattern</em> contains a relative path; 2) Any short (8.3) folder names in <em>FilePattern</em> itself are converted to their long names; 3) Characters in <em>FilePattern</em> are converted to uppercase or lowercase to match the case stored in the file system. This is useful for converting file names -- such as those passed into a script as command line parameters -- to their exact path names as shown by Explorer.</td>
  </tr>
  <tr id="LoopFileShortPath">
    <td>A_LoopFileShortPath</td>
    <td><p>The 8.3 short path and name of the file/folder currently retrieved. 例如: C:\MYDOCU~1\ADDRES~1.txt. If <em>FilePattern</em> contains a relative path rather than an absolute path, the path here will also be relative.</p>
      <p>To retrieve the complete 8.3 path and name for a single file or folder, specify its name for <em>FilePattern</em> as in this example:</p>
<pre>Loop Files, "C:\My Documents\Address List.txt"
    ShortPathName := A_LoopFileShortPath</pre>
        <p class="note"><strong>Note</strong>: This variable will be <strong>blank</strong> if the file does not have a short name, which can happen on systems where NtfsDisable8dot3NameCreation has been set in the registry. It will also be blank if <em>FilePattern</em> contains a relative path and the body of the loop uses <a href="SetWorkingDir.htm">SetWorkingDir</a> to switch away from the working directory in effect for the loop itself.</p></td>
  </tr>
  <tr id="LoopFileShortName">
    <td>A_LoopFileShortName</td>
    <td>The 8.3 short name, or alternate name of the file. If the file doesn't have one (due to the long name being shorter than 8.3 or perhaps because short-name generation is disabled on an NTFS file system), <em>A_LoopFileName</em> will be retrieved instead.</td>
  </tr>
  <tr id="LoopFileDir">
    <td>A_LoopFileDir</td>
    <td>The path of the directory in which <em>A_LoopFileName</em> resides. If <em>FilePattern</em> contains a relative path rather than an absolute path, the path here will also be relative. A root directory will not contain a trailing backslash. 例如: C:</td>
  </tr>
  <tr id="LoopFileTimeModified">
    <td>A_LoopFileTimeModified</td>
    <td>The time the file was last modified. Format <a href="FileSetTime.htm">YYYYMMDDHH24MISS</a>.</td>
  </tr>
  <tr id="LoopFileTimeCreated">
    <td>A_LoopFileTimeCreated</td>
    <td>The time the file was created. Format <a href="FileSetTime.htm">YYYYMMDDHH24MISS</a>.</td>
  </tr>
  <tr id="LoopFileTimeAccessed">
    <td>A_LoopFileTimeAccessed</td>
    <td>The time the file was last accessed. Format <a href="FileSetTime.htm">YYYYMMDDHH24MISS</a>.</td>
  </tr>
  <tr id="LoopFileAttrib">
    <td>A_LoopFileAttrib</td>
    <td>The <a href="FileGetAttrib.htm">attributes</a> of the file currently retrieved.</td>
  </tr>
  <tr id="LoopFileSize">
    <td>A_LoopFileSize</td>
    <td>The size in bytes of the file currently retrieved. Files larger than 4 gigabytes are also supported.</td>
  </tr>
  <tr id="LoopFileSizeKB">
    <td>A_LoopFileSizeKB</td>
    <td>The size in Kbytes of the file currently retrieved, rounded down to the nearest integer.</td>
  </tr>
  <tr id="LoopFileSizeMB">
    <td>A_LoopFileSizeMB</td>
    <td>The size in Mbytes of the file currently retrieved, rounded down to the nearest integer.</td>
  </tr>
</table>

<h2 id="Remarks">备注</h2>
<p>A file-loop is useful when you want to operate on a collection of files and/or folders, one at a time.</p>
<p>All matching files are retrieved, including hidden files. By contrast, OS features such as the DIR command omit hidden files by default. To avoid processing hidden, system, and/or read-only files, use something like the following inside the loop:</p>
<pre>if A_LoopFileAttrib ~= "[HRS]"  <em>; Skip any file that is either H (Hidden), R (Read-only), or S (System). See <a href="../Variables.htm#regex">~= operator</a>.</em>
    continue  <em>; Skip this file and move on to the next one.</em></pre>
<p>To retrieve files' relative paths instead of absolute paths during a recursive search, use <a href="SetWorkingDir.htm">SetWorkingDir</a> to change to the base folder prior to the loop, and then omit the path from the Loop (e.g. <code>Loop Files, "*.*", "R"</code>). That will cause <a href="#LoopFilePath">A_LoopFilePath</a> to contain the file's path relative to the base folder.</p>
<p>A file-loop can disrupt itself if it creates or renames files or folders within its own purview. 例如, if it renames files via <a href="FileMove.htm">FileMove</a> or other means, each such file might be found twice: once as its old name and again as its new name. To work around this, rename the files only after creating a list of them. 例如:</p>
<pre>FileList := &quot;&quot;
Loop Files, "*.jpg"
    FileList .= A_LoopFileName &quot;`n&quot;
Loop Parse, FileList, "`n"
    FileMove A_LoopField, "renamed_" A_LoopField</pre>
<p>Files in an NTFS file system are probably always retrieved in alphabetical order. Files in other file systems are retrieved in no particular order. To ensure a particular ordering, use the <a href="Sort.htm">Sort</a> function as shown in the Examples section below.</p>
<p>Files and folders with a complete path name longer than 259 characters are skipped over as though they do not exist. Such files are rare because normally, the operating system does not allow their creation.</p>
<p>请参阅 <a href="Loop.htm">Loop</a> 了解关于<a href="Block.htm">区块</a>, <a href="Break.htm">Break</a>, <a href="Continue.htm">Continue</a> 和 A_Index 变量(其存在于各种类型的循环中) 的相关信息.</p>

<h2 id="Related">相关</h2>
<p><a href="Loop.htm">Loop</a>, <a href="Break.htm">Break</a>, <a href="Continue.htm">Continue</a>, <a href="Block.htm">Blocks</a>, <a href="SplitPath.htm">SplitPath</a>, <a href="FileSetAttrib.htm">FileSetAttrib</a>, <a href="FileSetTime.htm">FileSetTime</a></p>

<h2 id="Examples">示例</h2>
<div class="ex" id="ExBasic">
<p><a href="#ExBasic">#1</a></p>
<pre>Loop Files, A_ProgramFiles "\*.txt", "R"  <em>; Recurse into subfolders.</em>
{
    Result := MsgBox("Filename = " A_LoopFilePath "`n`nContinue?",, "y/n")
    if Result = "No"
        break
}</pre>
</div>

<div class="ex" id="ExSize">
<p><a href="#ExSize">#2</a>: Calculate the size of a folder, including the files in all its subfolders:</p>
<pre>FolderSizeKB := 0
WhichFolder := DirSelect()  <em>; Ask the user to pick a folder.</em>
Loop Files, WhichFolder "\*.*", "R"
    FolderSizeKB += A_LoopFileSizeKB
MsgBox "Size of " WhichFolder " is " FolderSizeKB " KB."</pre>
</div>

<div class="ex" id="ExSortName">
<p><a href="#ExSortName">#3</a>: Retrieve file names sorted by name (see next example to sort by date):</p>
<pre>FileList := &quot;&quot;  <em>; Initialize to be blank.</em>
Loop Files, "C:\*.*"
    FileList .= A_LoopFileName &quot;`n&quot;
FileList := Sort(FileList, "R")  <em>; The R option sorts in reverse order. See <a href="Sort.htm">Sort</a> for other options.</em>
Loop Parse, FileList, "`n"
{
    if A_LoopField = &quot;&quot;  <em>; Ignore the blank item at the end of the list.</em>
        continue
    Result := MsgBox("File number " A_Index " is " A_LoopField ".  Continue?",, "y/n")
    if Result = "No"
        break
}</pre>
</div>

<div class="ex" id="ExSortDate">
<p><a href="#ExSortDate">#4</a>: Retrieve file names sorted by modification date:</p>
<pre>FileList := &quot;&quot;
Loop Files, A_MyDocuments "\Photos\*.*", "FD"  <em>; Include Files and Directories</em>
    FileList .= A_LoopFileTimeModified &quot;`t&quot; A_LoopFileName &quot;`n&quot;
FileList := Sort(FileList)  <em>; Sort by date.</em>
Loop Parse, FileList, "`n"
{
    if A_LoopField = &quot;&quot; <em>; Omit the last linefeed (blank item) at the end of the list.</em>
        continue
    FileItem := StrSplit(A_LoopField, A_Tab)  <em>; Split into two parts at the tab char.</em>
    Result := MsgBox("The next file (modified at " FileItem[1] ") is:`n" FileItem[2] "`n`nContinue?",, "y/n")
    if Result = "No"
        break
}</pre>
</div>

<div class="ex" id="ExFileCopy">
<p><a href="#ExFileCopy">#5</a>: Copy only the source files that are newer than their counterparts in the destination:</p>
<pre>CopyIfNewer:
<em>; Caller has set the variables CopySourcePattern and CopyDest for us.</em>
Loop Files, CopySourcePattern
{
    copy_it := false
    if !FileExist(CopyDest &quot;\&quot; A_LoopFileName)  <em>; Always copy if target file doesn't yet exist.</em>
        copy_it := true
    else
    {
        time := FileGetTime(CopyDest "\" A_LoopFileName)
        time := DateDiff(A_Now, A_LoopFileTimeModified, &quot;Seconds&quot;)  <em>; Subtract the source file's time from the destination's.</em>
        if time &lt; 0  <em>; Source file is newer than destination file.</em>
            copy_it := true
    }
    if copy_it
    {
        FileCopy A_LoopFilePath, CopyDest "\" A_LoopFileName, 1   <em>; Copy with overwrite=yes</em>
        if ErrorLevel
            MsgBox 'Could not copy "' A_LoopFilePath '" to "' CopyDest '\' A_LoopFileName '".'
    }
}
Return</pre>
</div>

<div class="ex" id="ExLongPath">
<p><a href="#ExLongPath">#6</a>: Convert filenames passed in via command-line parameters to long names, complete path, and correct uppercase/lowercase characters as stored in the file system.</p>
<pre>Loop A_Args.Length  <em>; For each parameter (or file dropped onto a script):</em>
{
    GivenPath := A_Args[A_Index]
    Loop Files, GivenPath, "FD"  <em>; Include files and directories.</em>
        LongPath := A_LoopFilePath
    MsgBox "The case-corrected long path name of file`n" GivenPath "`nis:`n" LongPath
}</pre>
</div>

</body>
</html>